package com.ljk.util.pdf;

import cn.hutool.core.codec.Base64Decoder;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.ljk.exception.UtilException;
import com.ljk.util.pdf.data.SignData;
import com.ljk.util.pdf.data.SignType;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

public class PdfUtil {

    private static final PdfPCell EMPTY_CELL = new PdfPCell();

    private static BaseFont baseFont;

    public static BaseFont getBaseFont() {
        if (baseFont == null) {
            try {
                baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            } catch (DocumentException | IOException e) {
                throw new RuntimeException("字体加载失败", e);
            }
        }
        return baseFont;
    }

    public static PdfPCell createSignCell(Font font, SignData signData) {
        if (signData == null || signData.getType() == null || signData.getData() == null) {
            return createCell(font, "", Element.ALIGN_CENTER);
        }
        if (signData.getType() == SignType.string) {
            return createCell(font, signData.getData(), Element.ALIGN_CENTER);
        }
        Image logo = null;
        try {
            if (signData.getType() == SignType.url) {
                logo = Image.getInstance(new URL(signData.getData()));
            } else if (signData.getType() == SignType.base64) {
                String data = signData.getData();
                if (data.contains("base64,")) {
                    data = data.substring(data.indexOf("base64,") + "base64,".length());
                }
                logo = Image.getInstance(Base64Decoder.decode(data));
            }
        } catch (BadElementException | IOException ignored) {
        }
        if (logo == null) {
            return createCell(font, "", Element.ALIGN_CENTER);
        }
        logo.setAlignment(Image.ALIGN_CENTER);
//        logo.scalePercent(60); //依照比例缩放
        logo.scaleToFit(60, 24);
        logo.setAlignment(Image.UNDERLYING);
        PdfPCell imageCell = new PdfPCell(logo);
        imageCell.setBorder(Rectangle.BOTTOM);
        imageCell.setPaddingBottom(1);
        imageCell.setPaddingTop(2);
        imageCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        imageCell.setHorizontalAlignment(Element.ALIGN_CENTER);
//        imageCell.setPadding(0);
        return imageCell;
    }

    /**
     * 将表格转换为单元格内容,并去掉边框
     *
     * @param table 表格
     */
    public static PdfPCell parseCell4Table(PdfPTable table) {
        table.setWidthPercentage(100);
        return parseCell(table);
    }

    /**
     * 将元素转换为单元格内容
     *
     * @param element 元素
     */
    public static PdfPCell parseCell(Element element) {
        PdfPCell cell = new PdfPCell();
        cell.setBorder(Rectangle.NO_BORDER);
        cell.setPadding(0);
        cell.addElement(element);
        return cell;
    }

    /**
     * 将一个单元格拆分成多个单元格,自动计算子单元格数量
     *
     * @param cellList 子单元格集合
     */
    public static PdfPCell parseOneCell(List<PdfPCell> cellList) {
        return parseOneCell(null, cellList);
    }

    /**
     * 将一个单元格拆分成多个单元格,自动计算子单元格数量
     *
     * @param cellList 子单元格数组
     */
    public static PdfPCell parseOneCell(PdfPCell... cellList) {
        return parseOneCell(null, cellList);
    }

    /**
     * 将一个单元格拆分成多个单元格
     *
     * @param relativeWidths 单元格长度比例
     * @param cellList       单元格列表
     */
    public static PdfPCell parseOneCell(float[] relativeWidths, PdfPCell... cellList) {
        if (cellList.length == 0) {
            return EMPTY_CELL;
        }
        return parseOneCell(relativeWidths, Arrays.asList(cellList));
    }

    /**
     * 将一个单元格拆分成多个单元格
     *
     * @param relativeWidths 单元格长度比例
     * @param cellList       单元格集合
     */
    public static PdfPCell parseOneCell(float[] relativeWidths, List<PdfPCell> cellList) {
        if (cellList == null || cellList.isEmpty()) {
            return EMPTY_CELL;
        }
        PdfPTable ke;
        if (relativeWidths == null) {
            ke = new PdfPTable(cellList.size());
        } else {
            ke = new PdfPTable(relativeWidths);
        }
        ke.setWidthPercentage(100);
        for (PdfPCell cell : cellList) {
            ke.addCell(cell);
        }
        return parseCell4Table(ke);
    }

    /**
     * 创建空白间隔
     */
    public static void createBlank(Document document, float height) throws DocumentException {
        // 添加指定高度的空白
        document.add(new Chunk("\n")); // 添加两个空行
        Chunk blankChunk = new Chunk(" ");
        blankChunk.setLineHeight(height);
        document.add(blankChunk);
    }

    /** 创建空白单元格 */
    public static PdfPCell createBankCell(float height) {
        PdfPCell cell = new PdfPCell(new Paragraph(""));
        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
        cell.setFixedHeight(height);
        cell.setBorder(Rectangle.NO_BORDER);
        return cell;
    }

    /** 创建空白单元格 */
    public static PdfPCell createBankCell() {
        PdfPCell cell = new PdfPCell(new Paragraph(""));
        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
        cell.setBorder(Rectangle.NO_BORDER);
        return cell;
    }

    /**
     * 创建文字单元格
     *
     * @param font  字体
     * @param value 值
     * @param align 水平对齐方式
     */
    public static PdfPCell createCell(Font font, String value, int align) {
        return createCell(font, value, Element.ALIGN_MIDDLE, align);
    }

    /**
     * 创建文字单元格
     *
     * @param font          字体
     * @param value         值
     * @param verticalAlign 垂直对齐方式
     * @param align         水平对齐方式
     */
    public static PdfPCell createCell(Font font, String value, int verticalAlign, int align) {
        if (value == null) {
            value = "";
        }
        PdfPCell cell = new PdfPCell();
        cell.setPhrase(new Phrase(new Chunk(value, font).setLineHeight(15.0f)));
        cell.setVerticalAlignment(verticalAlign);
        cell.setHorizontalAlignment(align);
        cell.setBorder(Rectangle.NO_BORDER);
//        cell.setBorder(Rectangle.BOX);
        return cell;
    }

    /**
     * 合并pdf
     *
     * @param files   pdf文件
     * @param newfile 合并后的pdf
     */
    public static boolean mergePdfFiles(String[] files, String newfile) {
        boolean retValue;
        Document document = null;
        PdfReader reader = null;
        try (OutputStream fos = Files.newOutputStream(Paths.get(newfile));) {
            document = new Document(new PdfReader(files[0]).getPageSize(1));
            PdfCopy copy = new PdfCopy(document, fos);
            document.open();
            for (String file : files) {
                reader = new PdfReader(file);
                int n = reader.getNumberOfPages();
                for (int j = 1; j <= n; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
                reader.close();
            }
            retValue = true;
            copy.flush();
            document.close();
            copy.close();
        } catch (Exception e) {
            throw new UtilException("pdf合并报错:" + e.getMessage(), e);
        } finally {
            if (document != null) {
                document.close();
            }
            if (reader != null) {
                reader.close();
            }
        }
        return retValue;
    }

}
